from mpython import *
import time, onewire, ds18x20, struct, ntptime
import machine
from servo import Servo
from machine import UART, time_pulse_us, RTC, Pin, I2C
from utime import sleep_us
line_count = 7445
def binary_search_for_gb2312(test_string):
        gb2312_encoded_text = b''  # 初始化空字节串
        for char in test_string:
            target_hex = hex(ord(char))[2:]  # 获取字符的Unicode编码的十六进制表示
            with open("gb2312.txt", 'r') as file:
                low, high = 0, line_count
                found = False  # 标记是否找到编码
                while low <= high:
                    mid = (low + high) // 2
                    file.seek(mid * 10)
                    line = file.readline().strip()
                    if line:
                        key, value = line.split(' ')
                        if key.lower() == target_hex:
                            bytes_obj = bytes(int(value[i:i+2], 16) for i in range(0, len(value), 2))
                            gb2312_encoded_text += bytes_obj
                            found = True
                            break  # 找到后退出循环
                        elif key.lower() < target_hex:
                            low = mid + 1
                        else:
                            high = mid - 1
                if not found:
                    print("C.")
                    # 对于未找到的字符可以选择忽略或者处理
        return gb2312_encoded_text
class AHT20(object):#AHT20温湿度传感器
    def __init__(self, i2c=i2c):
        # 初始化I2C总线
        self.i2c = i2c
        self.address = 0x38
    def _read_data(self):
        self.i2c.writeto(self.address, b'\xAC\x33\x00')
        time.sleep_ms(100)
        return self.i2c.readfrom(self.address, 6)
    def read_temp(self):
        data = self._read_data()
        temperature = (((data[3] & 0x0F) << 16) + (data[4] << 8) + data[5]) * 200 / (1 << 20) - 50
        return round(temperature, 1)
    def read_hum(self):
        data = self._read_data()
        humidity = ((data[1] << 12) + (data[2] << 4) + (data[3] >> 4)) * 100 / (1 << 20)
        return round(humidity, 1)
class TTS:#语音合成模块
    def __init__(self, uart_num=2, baud_rate=115200, tx_pin=Pin.P8, rx_pin=-1):
        self.uart = machine.UART(uart_num, baudrate=baud_rate, tx=tx_pin, rx=rx_pin)
    def speak(self, text):
        if 'a' <= text[0].lower() <= 'z':# 检查第一个字符是否为英文
            # 第一个字符是英文，假定整个文本都是英文
            self._send_command(text.encode('utf-8'), command_code=0x01, encoding_parameter=0x01)
        else:# 否则，进行中文处理
            encoded_text = binary_search_for_gb2312(text)
            self._send_command(encoded_text, command_code=0x01, encoding_parameter=0x01)

    def speak_var(self, var):
        self._send_command(str(var).encode(), command_code=0x01, encoding_parameter=0x01)

    def set_parameter(self, parameter_type, level, params):
        if level in params:
            self._send_command(params[level], command_code=0x00, additional_length=3)
            print(params[level])
        else:
            print("输入数据不合理，范围为:0-9")
    def set_volume(self, volume_level):
        volume_params = {i: struct.pack('!BBBBB', 0xFD, 0x00, 0x06, 0x01, 0x01) + b'\x5B\x76' + bytes(str(i), 'ascii') + b'\x5D' for i in range(10)}
        self.set_parameter('volume', volume_level, volume_params)

    def set_speed(self, speed_level):
        speed_params = {i: struct.pack('!BBBBB', 0xFD, 0x00, 0x06, 0x01, 0x01) + b'\x5B\x73' + bytes(str(i), 'ascii') + b'\x5D' for i in range(10)}
        self.set_parameter('speed', speed_level, speed_params)

    def set_tone(self, tone_level):
        tone_params = {i: struct.pack('!BBBBB', 0xFD, 0x00, 0x06, 0x01, 0x01) + b'\x5B\x74' + bytes(str(i), 'ascii') + b'\x5D' for i in range(10)}
        self.set_parameter('tone', tone_level, tone_params)
    def _send_command(self, data, command_code, encoding_parameter=0x01, additional_length=0):
        data_length = len(data) + 2 + additional_length
        command_data = struct.pack('!BHBB', 0xFD, data_length, command_code, encoding_parameter) + data
        self.uart.write(command_data)
        
class Asr:#语音识别模块
    def __init__(self, baudrate=9600):
        self.uart = UART(1, baudrate=baudrate, tx=-1, rx=Pin.P9)
    def value(self):
        if self.uart.any():
            data = self.uart.read()
            integer_value = int.from_bytes(data, 'big')
            return integer_value
        else:
            return None
class RTC:
    def RTC_date():#获取日期
        rtc = RTC()
        dt = rtc.datetime()
        date_str = "{}年{}月{}日".format(dt[0], dt[1], dt[2])
        return date_str
    def RTC_time():#获取时间
        rtc = RTC()
        dt = rtc.datetime()
        time_str = "{}:{}:{}".format(dt[4], dt[5], dt[6])
        return time_str

    def RTC_year():#获取时间-年
        rtc = RTC()
        dt = rtc.datetime()
        return dt[0]
    def RTC_month():#获取时间-月
        rtc = RTC()
        dt = rtc.datetime()
        return dt[1]
    def RTC_day():#获取时间-日
        rtc = RTC()
        dt = rtc.datetime()
        return dt[2]
    def RTC_hour():#获取时间-时
        rtc = RTC()
        dt = rtc.datetime()
        return dt[4]
    def RTC_minute():#获取时间-分
        rtc = RTC()
        dt = rtc.datetime()
        return dt[5]
    def RTC_second():#获取时间-秒
        rtc = RTC()
        dt = rtc.datetime()
        return dt[6]

class SR04:#超声波传感器
    def __init__(self, pin):
        self._pin = pin
    def duration(self, timeout=1000000):
        machine.Pin(self._pin, mode=machine.Pin.OUT).value(0)
        time.sleep_us(2)
        machine.Pin(self._pin, mode=machine.Pin.OUT).value(1)
        time.sleep_us(5)
        machine.Pin(self._pin, mode=machine.Pin.OUT).value(0)
        pulse_time = machine.time_pulse_us(machine.Pin(self._pin, mode=machine.Pin.IN), 1, timeout)
        return pulse_time
    def distance_cm(self, timeout=1000000):
        range_in_centimeters = self.duration(timeout) // 29 // 2
        return range_in_centimeters
    def distance_mm(self, timeout=1000000):
        range_in_millimeters = self.duration(timeout) * (10 // 2) // 29
        return range_in_millimeters
    def distance_inch(self, timeout=1000000):
        range_in_inches = self.duration(timeout) // 74 // 2
        return range_in_inches
    
class DS18B20:#DS18B20温度传感器
    def __init__(self, pin,device_index=0):
        self.ds_pin = Pin(pin)
        self.ds_sensor = ds18x20.DS18X20(onewire.OneWire(self.ds_pin))
    def scan_devices(self):
        return self.ds_sensor.scan()
    def temp(self, device_index=0):
        roms = self.scan_devices()
        if roms:
            self.ds_sensor.convert_temp()
            time.sleep_ms(750)
            return round(self.ds_sensor.read_temp(roms[device_index]),1)
        else:
            raise Exception("No DS18B20 devices found.")
class Button:
    def __init__(self):
        # 定义按钮连接的GPIO引脚
        self.pin_a = Pin(0, Pin.IN)
        self.pin_b = Pin(2, Pin.IN)

    def get_a(self):
        # 读取A按钮状态
        return not self.pin_a.value()

    def get_b(self):
        # 读取B按钮状态
        return not self.pin_b.value()

# 创建按钮管理器实例
button = Button()